package com.apotik.legenda.util;

import java.awt.Image;
import java.awt.event.KeyEvent;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.List;

import javax.swing.ImageIcon;
import javax.swing.JOptionPane;

import org.hibernate.Criteria;
import org.hibernate.classic.Session;
import org.hibernate.criterion.Restrictions;

import com.apotik.legenda.bean.TrxUniqueNumberBean;
import com.apotik.legenda.model.TransactionUniqueNumber;

public class AppUtil {

	public static String ROLE_SUPER_ADMIN 			= "SA";
	public static String ROLE_OWNER 				= "OWN";
	public static String ROLE_ADMIN 				= "ADR";
	public static String ROLE_KASIR 				= "KSR";
	public static String ROLE_STAFF 				= "STF";
	
	public static String TYPE_TRX_BEBAS				= "BEBAS";
	public static String TYPE_TRX_RESEP				= "RESEP";
	
	public static String PAYMENT_BY_TUNAI			= "TUNAI";
	public static String PAYMENT_BY_CARD			= "CARD";
	public static String PAYMENT_BY_ASRNSI			= "ASURANSI";
	
	public static String TRANSAKSI_STATUS_BARU 		= "N";
	public static String TRANSAKSI_STATUS_BAYAR 	= "Y";
	public static String TRANSAKSI_STATUS_BATAL 	= "C";
	public static String TRANSAKSI_STATUS_REFUND 	= "R";
	
	public static int MNEMONIC_BARU					= KeyEvent.VK_N;
	public static int MNEMONIC_BATAL				= KeyEvent.VK_C;
	public static int MNEMONIC_TAMBAH				= KeyEvent.VK_T;
	public static int MNEMONIC_EDIT					= KeyEvent.VK_E;
	public static int MNEMONIC_HAPUS				= KeyEvent.VK_H;
	public static int MNEMONIC_REFRESH				= KeyEvent.VK_R;
	
	
	/**
	 * Example: 19 to 000019
	 */
	public static String numberToString000000(int number){
		String result = "";
		
		if(number>100000){
			result = ""+number;
		}else{
			if(number>10000){
				result = "0"+number;
			}else{
				if(number>1000){
					result = "00"+number;
				}else{
					if(number>100){
						result = "000"+number;
					}else{
						if(number>10){
							result = "0000"+number;
						}else{
							result = "00000"+number;
						}
					}
				}
			}
		}
		
		return result;
	}
	
	private static String bulanHurufDuaDigit(int bulan){
		String result = "";
		
		if(bulan>9){
			result = ""+bulan;
		}else{
			result = "0"+bulan;
		}
		
		return result;
	}
	
	@SuppressWarnings("unchecked")
	public static TrxUniqueNumberBean generateTrxUniqueNumber(String code){
		TrxUniqueNumberBean result = null;
		
		try {
			Calendar cal = Calendar.getInstance();
			int month = cal.get(Calendar.MONTH)+1;
			int year = cal.get(Calendar.YEAR);
			
			Session session = HibernateUtil.getSessionFactory().openSession();
			
			Criteria cr = session.createCriteria(TransactionUniqueNumber.class);
			cr.add(Restrictions.eq("code", code));
			cr.add(Restrictions.eq("month", month));
			cr.add(Restrictions.eq("year", year));
			List<TransactionUniqueNumber> list = cr.list();
			TransactionUniqueNumber tun = null;
			if(list!=null){
				if(list.size()>0){
					tun = list.get(0);
				}
			}
			
			Long id = null;
			int number = 1;
			if(tun!=null){
				id = tun.getUniqueNumberId();
				number = tun.getNumber()+1;
			}
			
			String uniqueNumber = code+"-"+year+"-"+bulanHurufDuaDigit(month)+"-"+numberToString000000(number);
			
			TrxUniqueNumberBean trxUniqueNumberBean = new TrxUniqueNumberBean();
			trxUniqueNumberBean.setId(id);
			trxUniqueNumberBean.setUniqueNumber(uniqueNumber);
			trxUniqueNumberBean.setCode(code);
			trxUniqueNumberBean.setNumber(number);
			trxUniqueNumberBean.setMonth(month);
			trxUniqueNumberBean.setYear(year);
					
			result = trxUniqueNumberBean;
			
			session.close();
		} catch (Exception e) {
			JOptionPane.showMessageDialog(null, e.getMessage(), "Exception", JOptionPane.ERROR_MESSAGE);
		}
		
		
		return result;
	}
	
	/**
	 * Valid for 0-9
	 */
	public static boolean isNumber(String param){
		boolean result = false;
		
		try {
			Integer.parseInt(param);
			result = true;
		} catch (Exception e) {
			System.out.println("Excption: "+e.getMessage());
		}
		
		return result;
	}
	
	public static String formatStringIDR(int param){
		String result = "0";
		
		try {
			String paramStr = Integer.toString(param);
			double parsDouble = Double.parseDouble(paramStr);
			DecimalFormat formatter = new DecimalFormat("#,###.##");
			
			result = formatter.format(parsDouble);
			
		} catch (Exception e) {
			System.out.println("Exception: "+e.getMessage());
		}
		
		return result;
	}
	
	public static BigDecimal amountPersentasi(int percent, BigDecimal discountFrom, int scale){
		BigDecimal discountKali = new BigDecimal(percent).multiply(discountFrom);
		BigDecimal discountHsil = discountKali.divide(new BigDecimal(100), scale, RoundingMode.HALF_UP);
		return discountHsil;
	}
	
	public static BigDecimal amountSalesTrxObat(BigDecimal hargaSatuan, int quantity, BigDecimal sc, int diskon){
		BigDecimal sumHargaObat 	= hargaSatuan.multiply(new BigDecimal(quantity)).setScale(2, RoundingMode.HALF_UP);
		BigDecimal sumHarga 		= sumHargaObat.add(sc).setScale(2, RoundingMode.HALF_UP);
		BigDecimal discountAmount 	= AppUtil.amountPersentasi(diskon, sumHarga, 2);
		BigDecimal result 			= sumHarga.subtract(discountAmount);
		return result.setScale(0, RoundingMode.HALF_UP);
	}
	
	public static BigDecimal roundingDozensUp(BigDecimal param){
		BigDecimal result = param;
		
		String paramStr = param.toString();
		int length = paramStr.length();
			
		if(length<3){
			if(length==2){
				if(Integer.parseInt(paramStr)>94){
					result = new BigDecimal(100);
				}else{
					String firstStr = paramStr.substring(0, 1);
					int firstInt = Integer.parseInt(firstStr);
					
					String lastStr = paramStr.substring(1);
					int lastInt = Integer.parseInt(lastStr);
					
					int plus1 = firstInt;
					if(lastInt>4){
						plus1 = firstInt+1;
					}
					
					String rounding = plus1+"0";
					result = new BigDecimal(rounding);
				}
			}
		}else{
			if(length>2){
				int indexRatusan = length-3;
				String thirdStr = paramStr.substring(indexRatusan, length-2);
				String lastThreeStr = paramStr.substring(indexRatusan);
				
				if(Integer.parseInt(lastThreeStr)>Integer.parseInt(thirdStr+"00")){
					if(thirdStr.equalsIgnoreCase("9")){
						String firstToBeforeHundreds = paramStr.substring(0, indexRatusan);
						String genapkanStr = firstToBeforeHundreds+"000";
						int genapkanInt = Integer.parseInt(genapkanStr);
						
						int rounding = genapkanInt+1000;
						result = new BigDecimal(rounding);
					}else{
						int thirdInt = Integer.parseInt(thirdStr);
						int plus1 = thirdInt + 1;
						String hundredsStr = plus1 + "00";

						String rounding = paramStr.substring(0, indexRatusan)+ hundredsStr;
						result = new BigDecimal(rounding);
					}
				}
			}
		}
		
		return result;
	}
	
	public static String removeCharacters(String str, String chars){
		StringBuffer buffer = new StringBuffer();
		String replc = str;
		if(chars.equalsIgnoreCase(".")){
			chars = ":";
			replc = str.replace(".", ":");
		}
		
		String[] pecah = replc.split(chars);
		
		for(int i=0;i<pecah.length;i++){
			buffer.append(pecah[i]);
		}
		
		return buffer.toString();
	}
	
	@SuppressWarnings("rawtypes")
	public static ImageIcon resizeImage(Class classs, String resource, int width, int height){
		ImageIcon icon = new ImageIcon(classs.getResource(resource));
		Image img = icon.getImage().getScaledInstance(16, 16, Image.SCALE_SMOOTH);
		
		return new ImageIcon(img);
	}
	
	public static String formatIDRAlignRight(int param){
		String result = "";
		try {
			String paramStr = Integer.toString(param);
			double parsDouble = Double.parseDouble(paramStr);
			DecimalFormat formatter = new DecimalFormat("#,###.##");
			String idr = formatter.format(parsDouble);
			
			
			int lengthMax = 9;
			int lengthParam = idr.length();
			int addedZero = lengthMax-lengthParam;
			
			StringBuffer buffer = new StringBuffer();
			for(int i=0;i<addedZero;i++){
				buffer.append(" ");
			}
			
			result = buffer.toString()+idr;
			
		} catch (Exception e) {
			System.out.println("Exception: "+e.getMessage());
		}
		
		return result;
	}
	
	public static String convertNumberToTerbilang(double angka) {
		String[] nomina = { "", "satu", "dua", "tiga", "empat", "lima", "enam",
				"tujuh", "delapan", "sembilan", "sepuluh", "sebelas" };

		if (angka < 12) {
			return nomina[(int) angka];
		}

		if (angka >= 12 && angka <= 19) {
			return nomina[(int) angka % 10] + " belas ";
		}

		if (angka >= 20 && angka <= 99) {
			return nomina[(int) angka / 10] + " puluh " + nomina[(int) angka % 10];
		}

		if (angka >= 100 && angka <= 199) {
			return "seratus " + convertNumberToTerbilang(angka % 100);
		}

		if (angka >= 200 && angka <= 999) {
			return nomina[(int) angka / 100] + " ratus " + convertNumberToTerbilang(angka % 100);
		}

		if (angka >= 1000 && angka <= 1999) {
			return "seribu " + convertNumberToTerbilang(angka % 1000);
		}

		if (angka >= 2000 && angka <= 999999) {
			return convertNumberToTerbilang((int) angka / 1000) + " ribu " + convertNumberToTerbilang(angka % 1000);
		}

		if (angka >= 1000000 && angka <= 999999999) {
			return convertNumberToTerbilang((int) angka / 1000000) + " juta " + convertNumberToTerbilang(angka % 1000000);
		}

		return "";
	}
}
